/**
 * 
 */
package info.niwota.profile;

import info.niwota.profile.web.Helper;

import java.io.File;

import org.json.JSONException;
import org.json.JSONObject;

import android.app.Activity;
import android.content.Context;
import android.content.DialogInterface;
import android.content.DialogInterface.OnCancelListener;
import android.content.Intent;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.net.Uri;
import android.os.AsyncTask;
import android.os.Bundle;
import android.text.TextUtils;
import android.util.Log;
import android.view.View;
import android.view.View.OnClickListener;
import android.view.Window;
import android.widget.ImageView;
import android.widget.TextView;
import android.widget.Toast;

/**
 * @author qiangli
 * 
 */
public class BaseProfileActivity extends Activity implements OnClickListener {
	private static final String TAG = "BaseProfileActivity";

	private JSONObject prof;
	private Bitmap photo;

	private SpinDialog dialog;

	private void hideProgress() {
		try {
			if (dialog != null) {
				Window d = dialog.getWindow();
				if (d != null) {
					dialog.dismiss();
				}
				dialog = null;
			}

		} catch (Exception e) {
			e.printStackTrace();
		}
	}

	private void showProgress() {
		try {
			final Context ctx = this;
			CharSequence msg = ctx.getText(R.string.text_please_wait);
			dialog = SpinDialog.show(ctx, "", msg, true, true,
					new OnCancelListener() {
						public void onCancel(DialogInterface dialog) {
							CharSequence t = ctx
									.getText(R.string.text_canceled);
							Toast.makeText(ctx, t, Toast.LENGTH_SHORT).show();
						}
					});
		} catch (Exception e) {
			e.printStackTrace();
		}
	}
	private class LocationTask extends AsyncTask<Void, Void, Void> {
		private String location = null;
		
		@Override
		protected Void doInBackground(Void... params) {
			final Context ctx = BaseProfileActivity.this;
			try {
				location = Locations.getLocation(ctx);
			} catch (Exception e) {
				e.printStackTrace();
			}

			return null;
		}

		@Override
		protected void onPostExecute(Void result) {
			try {
				if (location != null) {
					TextView myloc = (TextView) findViewById(R.id.profile_mylocation_view);
					myloc.setText(location);
				}
				
			} catch (Exception e) {
				e.printStackTrace();
			}

		}

	}

	private LocationTask locationTask;
	
	private class ProfileTask extends AsyncTask<Void, Void, Void> {

		private Exception error;

		@Override
		protected void onCancelled() {
			hideProgress();
		}

		@Override
		protected void onPreExecute() {
			showProgress();
		}

		@Override
		protected Void doInBackground(Void... params) {
			error = null;
			prof = null;
			try {
				if (isPeer()) {
					prof = loadPeerProfile();
				} else {
					prof = Preferences
							.getProfileJSONObject(BaseProfileActivity.this, false);
				}
			} catch (Exception e) {
				error = e;
				
				e.printStackTrace();
			}
			photo = null;
			try {
				if (isPeer()) {
					final boolean thumb = true; //TODO 
					photo = loadPeerPhoto(thumb);
				}
			} catch (Exception e) {
				error = e;
				
				e.printStackTrace();
			}
			return null;
		}

		@Override
		protected void onPostExecute(Void result) {
			if (error != null) {
				showError(error);
				
			} else {

				try {
					if (prof != null) {
						showProfile(prof);
					}
				} catch (Exception e) {
					e.printStackTrace();
				}
	
				try {
					if (photo != null) {
						showPhoto(photo);
					} else if (!isPeer()) {
						showMyPhoto();
					}
				} catch (Exception e) {
					e.printStackTrace();
				}
			}

			hideProgress();
		}

	}

	protected String peer;
	
	private ProfileTask profileTask;
	
	private class VignetteTask extends AsyncTask<Void, Void, Void> {
		private Exception error;
		private File vignette;

		@Override
		protected void onCancelled() {
			hideProgress();
		}

		@Override
		protected void onPreExecute() {
			showProgress();
		}
		@Override
		protected Void doInBackground(Void... params) {
			error = null;
			Context ctx = BaseProfileActivity.this;
			try {
				//use cache, cached vignette will be removed after refresh
				vignette = Helper.getPeerPhotoFile(ctx, peer,  false, false);
			} catch (Exception e) {
				error = e;
				
				e.printStackTrace();
			}
			return null;
		}

		@Override
		protected void onPostExecute(Void result) {
			if (error != null) {
				showError(error);
			} else {
				try {
					showPhoto(vignette);
				} catch (Exception e) {
					e.printStackTrace();
				}
			} 
			hideProgress();
		}
	}

	private boolean nocache;

	private VignetteTask vignetteTask;

	@Override
	protected void onCreate(Bundle savedInstanceState) {

		super.onCreate(savedInstanceState);

	}

	private Bitmap loadPeerPhoto(boolean thumb) throws Exception {
		return Helper.loadPeerPhoto(this, peer, thumb, nocache);
	}

	public void showError(Exception error) {
		Toast.makeText(this, getString(R.string.format_error, error.getMessage()), Toast.LENGTH_SHORT).show();
	}

	private void showPhoto(Bitmap photo) {
		ImageView img = (ImageView) findViewById(R.id.profile_photo);
		try {
			img.setImageBitmap(photo);
		} catch (Error e) {
			// ignore oom
			e.printStackTrace();
		}
	}

	private void showMyPhoto() {
		ImageView img = (ImageView) findViewById(R.id.profile_photo);
		try {
			File file = Helper.getMyPhotoThumbnail(this);
			if (file != null) {
				Bitmap bm = BitmapFactory.decodeFile(file.getPath());
				img.setImageBitmap(bm);
			} else {
				img.setImageResource(R.drawable.ic_contact_picture);
			}

		} catch (Error e) {
			// ignore oom
			e.printStackTrace();
		}
	}

	private boolean isPeer() {
		return (!TextUtils.isEmpty(peer));
	}

	protected void loadLocation() {
		try {
			cancelLoadLocation();
			//
			locationTask = new LocationTask();
			locationTask.execute();
		} catch (Exception e) {
			e.printStackTrace();
		}
	}
	
	protected void cancelLoadLocation() {
		try {
			if (locationTask != null) {
				locationTask.cancel(true);
			}
		} catch (Exception e) {
			e.printStackTrace();
		} finally {
			locationTask = null;
		}
	}

	@Override
	protected void onResume() {
		super.onResume();
		
		if (Debug.DEBUG) {
			Log.d(TAG, "onResume");
		}
		
		loadProfile(false);
	}

	protected void loadProfile(boolean nocache) {
		this.nocache = nocache;
		try {
			cancelLoadProfile(); // just in case
			//
			profileTask = new ProfileTask();
			profileTask.execute();
		} catch (Exception e) {
			e.printStackTrace();
		}
	}

	@Override
	protected void onPause() {
		super.onPause();
		if (Debug.DEBUG) {
			Log.d(TAG, "onPause");
		}

		cancelLoadProfile();
	
	}

	protected void cancelLoadProfile() {
		try {
			if (profileTask != null && !profileTask.isCancelled()) {
				profileTask.cancel(true);
			}
		} catch (Exception e) {
			e.printStackTrace();
		} finally {
			profileTask = null;
		}
	}

	private JSONObject loadPeerProfile() throws Exception {
		return Helper.getPeerProfile(this, peer, nocache);
	}

	private void showProfile(JSONObject p) {
		ImageView img = (ImageView) findViewById(R.id.profile_photo);
		img.setOnClickListener(this);
		
		TextView vname = (TextView) findViewById(R.id.profile_name);
		vname.setText(getString(p, Preferences.PROFILE_NAME));

		//
		TextView vgender = (TextView) findViewById(R.id.profile_gender);
		int sex = 0;
		try {
			sex = p.getInt(Preferences.PROFILE_GENDER);
		} catch (JSONException e) {
		}
		vgender.setText("Gender: " + (sex == 1 ? "M" : (sex == 2 ? "F" : "")));
		//
		TextView dob = (TextView) findViewById(R.id.profile_birthday);
		CharSequence bday = getString(p, Preferences.PROFILE_DOB);
		dob.setText("DOB: " + (bday == null ? "" : bday));

		//
		showItem(p, R.id.profile_welcome, Preferences.PROFILE_WELCOME);

		showItem(p, R.id.profile_mylocation, Preferences.PROFILE_LOCATION);
		showItem(p, R.id.profile_mytime, Preferences.PROFILE_TIME);

		showItem(p, R.id.profile_phone, Preferences.PROFILE_CALL);
		showItem(p, R.id.profile_texting, Preferences.PROFILE_TEXT);
		showItem(p, R.id.profile_email, Preferences.PROFILE_EMAIL);

		// showItem(p, R.id.profile_im, Preferences.PROFILE_CHAT);

		showItem(p, R.id.profile_website, Preferences.PROFILE_WEBSITE);
		showItem(p, R.id.profile_address, Preferences.PROFILE_ADDRESS);

		//
		showItem(p, R.id.profile_note, Preferences.PROFILE_NOTE);
		
		//
		TextView vmod = (TextView) findViewById(R.id.profile_modified);
		String mod = null;
		try {
			long date = Long.parseLong(getString(p, Preferences.PROFILE_MODIFIED));
			if (date > 0) {
				mod = getString(R.string.format_profile_last_mofidied, Profiles.formatModified(date));
			}
		} catch (Exception e) {
			//
		}
		vmod.setText(mod);
	}

	private void showItem(JSONObject p, int view, String key) {
		TextView v = (TextView) findViewById(view);

		CharSequence s = getString(p, key);
		v.setText(s);
		if (s != null) {
			v.setOnClickListener(this);
			v.setVisibility(View.VISIBLE);
		} else {
			v.setVisibility(View.GONE);
		}
	}

	private String getString(JSONObject p, String name) {
		try {
			return p.getString(name);
		} catch (JSONException e) {
			//
		}
		return null;
	}

	public void launch(Intent i, String ti) {
		try {
			Intent ci = Intent.createChooser(i, ti);
			ci.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
			startActivity(ci);
		} catch (Exception e) {
			e.printStackTrace();
		}
	}

	public void onClick(View v) {
		int id = v.getId();
		if (Debug.DEBUG) {
			Log.d(TAG, "onclick " + id + " profile: " + prof);
		}
		if (prof == null) {
			return;
		}
		switch (id) {
		case R.id.profile_btn_fav:
			toggleFav();
			break;
		case R.id.profile_photo:
			doViewPhoto();
			break;
		case R.id.profile_mylocation:
			String loc = getString(prof, Preferences.PROFILE_LOCATION);
			if (loc != null) {
				doViewMap(loc);
			}
			break;
		case R.id.profile_phone:
			String phone = getString(prof, Preferences.PROFILE_CALL);
			if (phone != null) {
				Intent i = Profiles.createCallIntent(phone);
				String ti = phone;
				launch(i, ti);
			}
			break;
		case R.id.profile_texting:
			String text = getString(prof, Preferences.PROFILE_TEXT);
			if (text != null) {
				Intent i = Profiles.createTextIntent(text);
				String ti = text;
				launch(i, ti);
			}
			break;
		case R.id.profile_email:
			String email = getString(prof, Preferences.PROFILE_EMAIL);
			if (email != null) {
				Intent i = Profiles.createEmailIntent(new String[] { email });
				String ti = email;
				launch(i, ti);
			}
			break;
		case R.id.profile_im:
			// TODO
			break;
		case R.id.profile_website:
			String url = getString(prof, Preferences.PROFILE_WEBSITE);
			if (url != null) {
				doView(url);
			}
			break;
		case R.id.profile_address:
			String addr = getString(prof, Preferences.PROFILE_ADDRESS);
			if (addr != null) {
				doViewMap(addr);
			}
			break;
		}
	}

	private void toggleFav() {
		//peer star/unstar
		if (isPeer()) {
			boolean star = !Preferences.isPeerStarred(this, peer);
			setFavImage(star);
			Preferences.starPeer(this, peer, star);
		} else {
			//TODO edit activity?
		}
	}

	private void setFavImage(boolean starred) {
		ImageView btn = (ImageView) findViewById(R.id.profile_btn_fav);
		btn.setImageResource(starred ? R.drawable.favorite48: R.drawable.favorite48_grey);
	}

	private void doView(String uri) {
		try {
			Intent i = new Intent();
			i.setAction(Intent.ACTION_VIEW);
			i.setData(Uri.parse(uri));
			startActivity(i);
		} catch (Exception e) {
			e.printStackTrace();
		}
	}

	private void doViewMap(String loc) {
		try {
			Intent i = Profiles.createMapIntent(this, loc);
			String ti = loc;
			launch(i, ti);
		} catch (Exception e) {
			e.printStackTrace();
		}
	}

	private void doViewPhoto() {
		if (isPeer()) {
			if (vignetteTask != null) {
				vignetteTask.cancel(true);
			}
			vignetteTask = new VignetteTask();
			vignetteTask.execute();
			return;
		} else {
			//local, use full image
			final String uri = Preferences.getProfilePhoto(this);
			if (!TextUtils.isEmpty(uri)) {
				Utils.startViewActivity(this, Uri.parse(uri), "image/*");
			}
		}
	}

	private void showPhoto(File file) {
		try {
			if (file != null) {
				Utils.startViewActivity(this, Uri.fromFile(file), "image/*");
			}
		} catch (Exception e) {
			e.printStackTrace();
		}
	}
	
}
